#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<stdlib.h>

#define NUM 1024
struct MyFILE_{
  int fd;
  char buffer[1024];
  int end;//充当缓冲区结尾
};
typedef struct MyFILE_ MyFILE;

MyFILE *fopen_(const char *pathname,const char *mode)
{
  assert(pathname);
  assert(mode);
  MyFILE *fp = NULL;

  if(strcmp(mode,"r")==0)
  {

  }
  else if(strcmp(mode,"r+")==0)
  {

  }
  else if(strcmp(mode,"w")==0)
  {
    int fd=open(pathname,O_WRONLY | O_TRUNC | O_CREAT,0666);
    if(fd >= 0)
    {
      fp = (MyFILE*)malloc(sizeof(MyFILE));
      memset(fp,0,sizeof(MyFILE));
      fp->fd=fd;
    } 
  }
  else if(strcmp(mode,"w+")==0)
  {

  }
  else if(strcmp(mode,"a")==0)
  {

  }
  else if(strcmp(mode,"a+")==0)
  {

  }
  else{

  }
  return fp;
}

void fputs_(const char *message,MyFILE *fp)
{
  assert(message);
  assert(fp);

  strcpy(fp->buffer+fp->end,message);
  fp->end+=strlen(message);

  //for debug
  printf("%s\n",fp->buffer);

  //暂时没有刷新,刷新策略是谁来执行的呢？用户通过执行C标准库中的代码逻辑，未完成刷新动作。
  //效率提高体现再哪里呢？因为c提共了缓冲区，那么我们就通过策略，减少了IO的执行次数（不是数据量）
  if(fp->fd==0)
  {

  }
  else if(fp->fd==1)
  {
    if(fp->buffer[fp->end-1]=='\n')
    {
      fprintf(stderr,"fflush: %s",fp->buffer);//往fd=2打
      write(fp->fd,fp->buffer,fp->end);
      fp->end=0;
    }
  }
  else if(fp->fd==2)
  {

  }
  else
  {

  }
}

void fflush_(MyFILE *fp)
{
  assert(fp);

  if(fp->end!=0)
  {
    //暂且认为刷新了  其实是把数据写到了内核
    write(fp->fd,fp->buffer,fp->end);
    syncfs(fp->fd);//将数据写入到磁盘
    fp->end=0;
  }
}

void fclose_(MyFILE *fp)
{
  assert(fp);
  fflush_(fp);
  close(fp->fd);
  free(fp);
}

int main()
{
  //close(1);
  MyFILE *fp = fopen_("./log.txt","w");
  if(fp==NULL)
  {
    printf("open file fail\n");
    return 1;
  }

  fputs_("one: hello world ",fp);
  fork();
  fclose_(fp);
}



//int main(int argc,char *argv[])
//int main()
//{
  ////C语言提共
  //printf("helol printf\n");
  //fprintf(stdout,"helloc fprintf\n");
  //const char*s="hello fputs\n";
  //fputs(s,stdout);
  //
  ////OS提供
  //const char* ss="hello write\n";
  //write(1,ss,strlen(ss));
  //
  //fork();//创建子进程




 // if(argc!=2)
 // {
 //   return 2;
 // }
 //
 // //int fd=open("log.txt",O_WRONLY | O_CREAT | O_TRUNC);//输出
 // int fd=open("log.txt",O_WRONLY | O_CREAT | O_APPEND);//追加
 // if(fd<0)
 // {
 //   perror("open");
 //   return 1;
 // }
 //
 // dup2(fd,1);//用后者替代前者
 //
 // fprintf(stdout,"%s\n",argv[1]);//stdout->1->显示器


 // close(0);
 // //int fd=open("log.txt",O_RDONLY);
 // //int fd=open("log.txt",O_RDONLY);
 // //int fd=open("log.txt",O_RDONLY | O_TRUNC | O_CREAT);//输出重定向
 // int fd=open("log.txt",O_RDONLY | O_APPEND | O_CREAT);//追加重定向
 // if(fd<0)
 // {
 //   perror("open");
 //   return 1;
 // }
 // printf("fd: %d\n",fd);
 // char buffer[64];
 // fgets(buffer,sizeof(buffer),stdin);
 //
 // printf("%s\n",buffer);



 /* close(0);
  //这里fd的分配规则是：最小的，没有被占用的文件描述符

  int fd=open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
  if(fd<0)
  {
    perror("open");
    return 1;
  }

  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
  printf("fd: %d\n",fd);
*/
  //close(fd);
//  return 0;
//}
